home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / VideoToolbox 96.06.15 / VideoToolboxSources / Luminance.h < prev    next >
Text File  |  1995-10-05  |  12KB  |  238 lines

  1. /*
  2. Luminance.h
  3. This is the include file for Luminance.c and ReadLuminanceRecord.c
  4. Copyright 1989-1995 (c) Denis G. Pelli 
  5. HISTORY:
  6. 9/18/90    dgp    Changed all instances of "v" to "V". The final version of the Pelli
  7.             & Zhang (1991) manuscript refers to a nominal voltage v; this file
  8.             now refers to the "equivalent number" V; they are related by V=255*v.
  9.             To avoid "breaking" all the old LuminanceRecord.h files, I've 
  10.             introduced a #define that converts vMin & vMax to VMin & VMax. However,
  11.             this is a temporary fix. I'll probably remove the define in a few months,
  12.             so you should still update any old calibration files, either by editing,
  13.             replacing "vM" by "VM" or by redoing the calibration.
  14. 9/24/90    dgp    Added screen & date. Renamed nBackground to VBackground.
  15.             Renamed index to lastIndex.
  16. 9/28/90    dgp    Renamed lastIndex to latestIndex. Spruced up some of the comments.
  17. 10/31/90 dgp Added the conditional FAST_LUMINANCE. Setting it to 1 (true) makes
  18.             SetLuminancesAndRange() run twice as fast, by using fixed point
  19.             arithmetic instead of doubles. Setting it to 0 (false) causes the
  20.             same code to be compiled to use doubles. Note that the prototypes of
  21.             some internal functions (names beginning with underscore) are conditional
  22.             on FAST_LUMINANCE.
  23. 11/6/90 dgp Replaced Milli by Fixed. 
  24. 11/8/90 dgp    Eliminated gamma slope table shiftedLSlope[] since the speed-up it offered
  25.             was too small to measure.
  26. 7/30/91    dgp    Added prototype for ReadLuminanceRecord().
  27. 8/4/91    dgp    Change ReadLuminanceRecord() to return type int.
  28. 8/5/91    dgp    Trying to compile under MPW C 3.2 uncovered a name-space conflict.
  29.             The MPW C 3.2 CType.h header file defines _L as a preprocessor constant,
  30.             whereas Luminance.h uses it as a field of the LuminanceTable structure,
  31.             and as a parameter name.
  32.             The THINK C 4.05 ctype.h header file names the same constant __LOWR,
  33.             which of course doesn't conflict. The obvious solution would be to
  34.             change MPW's CType.h _L to _LOWR, but that would compromise portability.
  35.             I decided not to change _L in Luminance.h and Luminance.c,
  36.             because it would be hard to do that in a way that wouldn't compromise 
  37.             the readability of the code. However, I did do a quick hack, 
  38.             about ten lines below, that redefines _L as an enum, which solves the
  39.             problem, provided CType.h is included before Luminance.h in files that
  40.             need to explicitly access _L. In fact _L is intended for use
  41.             only by the routines that are in Luminance.c, so I suspect the
  42.             problem is solved.
  43. 12/17/92    dgp Removed obsolete support for THINK C 4. 
  44. 12/21/92 dgp Added dacSize and leftShift.
  45. 6/5/93    dgp    Removed the ancient #defines that were required to read ≤1990 calibration
  46.             files.
  47. 8/12/93    dgp    updated ReadLuminanceRecord() prototype to match source file.
  48. 8/1/94    dgp Renamed "_L" to "_Lu" to avoid conflict with _L() macro defined in fp.h.
  49. 10/17/94 dgp capitalized luminanceRecord to LuminanceRecord, but retained a typedef
  50.             of old for backward compatibility.
  51. 4/30/95 dgp capitalized luminanceTable to LuminanceTable, but retained a typedef
  52.             of old for backward compatibility.
  53. */
  54.  
  55. #pragma once        /* suppress multiple inclusions of this file */
  56. #ifndef _LUMINANCE_    /* suppress multiple inclusions of this file */
  57. #define _LUMINANCE_
  58.  
  59. #ifndef __QUICKDRAW__
  60.     #include <QuickDraw.h>
  61. #endif
  62. #ifndef __SOUND__
  63.     #include <Sound.h>
  64. #endif
  65.  
  66. /* LINEAR_V_DOMAIN is the maximum interval in V over which the gamma function is
  67. to be assumed linear by LToV(). The value 4 gives almost the same accuracy as 1, yet
  68. results in SetLuminances() on a Mac II taking only 29 ms instead of 50 ms. 
  69. See _LToV() in Luminance.c  for more information. */
  70.  
  71. #define MACINTOSH    1        /* set to 0 to use on any other computer */
  72. #define LINEAR_V_DOMAIN 4    /* see above */
  73. #define FAST_LUMINANCE 1    /* 1 for Fixed math (twice as fast), 0 for double math */
  74. #define DACS 3                /* number of digital-to-analog converters that we support */
  75. #define COLORS 256            /* size of ColorSpec table */
  76. #define MAX_COEFFICIENTS 9    /* polynomial fit */
  77. #define LUMINANCES_IN_TABLE 128    /* size of gamma table */
  78.  
  79. #if FAST_LUMINANCE & !defined(__TOOLUTILS__)
  80.     #include <ToolUtils.h>    /* prototypes for FixMul etc. */
  81. #endif
  82.  
  83. typedef struct{
  84.     ColorSpec table[COLORS];    /* a table of values destined for the clut */
  85. } Clut;
  86.  
  87. enum {Michelson,Weber};    /* contrastType */
  88.  
  89. typedef struct {
  90.     short exists;    /* set to luminanceSet once this table has been initialized */
  91.     short latestIndex;/* last-used index of LR.L._Lu[] is good place to start search */
  92.     #if FAST_LUMINANCE
  93.         Fixed _VMin;    /* bounds monotonic part of domain of gamma function */
  94.         Fixed _VMax;    /* bounds monotonic part of domain of gamma function */
  95.         Fixed _dV;        /* V = _VMin,_VMin+_dV,_VMin+2dV,_VMin+3dV, . . . ,_VMax */
  96.                         /* _dV=(_VMax-_VMin)/(LUMINANCES_IN_TABLE-1) */
  97.         Fixed _Lu[LUMINANCES_IN_TABLE];
  98.         long LShift;    /* bit shift to be applied to luminance differences */
  99.     #else
  100.         double _VMin;    /* bounds monotonic part of domain of gamma function */
  101.         double _VMax;    /* bounds monotonic part of domain of gamma function */
  102.         double _dV;        /* V = _VMin,_VMin+_dV,_VMin+2dV,_VMin+3dV, . . . ,_VMax */
  103.                         /* _dV=(_VMax-_VMin)/(LUMINANCES_IN_TABLE-1) */
  104.         double _Lu[LUMINANCES_IN_TABLE];
  105.     #endif
  106. } LuminanceTable;
  107.  
  108. typedef struct {    /* "table" MUST be the first thing in the structure! */
  109.     ColorSpec table[COLORS];/* a table of values destined for the clut */
  110.     short dacSize;        /* bits */
  111.     short leftShift;    /* bit shift of V to produce 16 bit value=16-dacSize */
  112.     short VMin,VMax;    /* lowest and highest DAC values allowed: 0 and 255 */
  113.     double LMin,LMax;    /* luminances at VMin & VMax */
  114.     double LBackground;    /* the background luminance used during luminance calibration */
  115.     short VBackground;    /* the background number used during luminance calibration */
  116.     short screen;        /* device=GetScreenDevice(LR.screen); */
  117.     char *id;            /* make, model, and serial number of monitor */
  118.     char *name;            /* informal name of monitor */
  119.     char *date;            /* when calibrated */
  120.     char *notes;        /* description of calib conditions: who & how */
  121.     double dpi;            /* pixels per inch */
  122.     double Hz;            /* frames per second */
  123.     char *units;        /* Luminance units, e.g. "cd/m^2" */
  124.     long coefficients;    /* the number of coefficients, not more than MAX_COEFFICIENTS, */
  125.                         /*    usually 9, giving an 8th-order polynomial, */
  126.     double p[MAX_COEFFICIENTS];
  127.                         /* coefficients of a polynomial in value V, yielding L in cd/m^2 */
  128.     double polynomialError;    /* RMS error of polynomial fit */
  129.                         /* L(V)=p[0]+p[1]*V+p[2]*V*V+ . . . ±polynomialError */
  130.     double q[3];        /* coefficients of a quadratic polynomial in V */
  131.     double quadraticError;    /* RMS error of quadratic fit */
  132.                         /* L(V)=q[0]+q[1]*V+q[2]*V*V±quadraticError */
  133.     double power[4];    /* coefficients of a power law fit */
  134.     double powerError;    /* RMS error of power law fit */
  135.                         /* L(V)=power[0]+Rectify(power[1]+power[2]*V)^power[3]±powerError */
  136.                         /* Rectify(x)=x if x≥0, Rectify(x)=0 if x<0 */
  137.                         /* Pelli & Zhang (1991) Eqs.9&10 use symbols: */
  138.                         /* v=V/255, alpha=power[0], beta=power[1], kappa=power[2]*255, */
  139.                         /* gamma=power[3] */
  140.     double fixedPower[4];    /* coefficients of a power law fit, with fixed exponent */
  141.     double fixedPowerError;    /* RMS error of power law fit */
  142.                         /* L(V)=fixedPower[0]+Rectify(fixedPower[1]+fixedPower[2]*V)^fixedPower[3]±fixedPowerError */
  143.     double r,g,b;        /* voltage gains for the three pathways. r+g+b=1. All must be ≥0. */
  144.     double gainAccuracy;/* possible error in r,g,b */
  145.     double gm;            /* The monitor's contrast gain. The Michelson contrast produced by
  146.                             a small Δv at the background luminance is c=gm*Δv */
  147.     /* The rest of the parameters are for temporary storage by SetLuminanceRange() */
  148.     double lowLuminance;    /* the bottom of the range */
  149.     double highLuminance;    /* the top of the range */
  150.     short rangeSet;            /* a check that the range really has been set */
  151.     short dacs;                /* the number of dacs with nonzero gain, usually 1 or 3 */
  152.     short fixed;            /* the number of dacs whose value will be fixed for this range */
  153.     short dac[DACS];        /* which dac corresponds to each gain, r=0,g=1,b=2 */
  154.     double gain[DACS];        /* the ordered normalized gains of the Video Attenuator */
  155.     double VHalfStep;        /* half a step of the finest dac */
  156.     double VFixed;            /* the value produced by the fixed dacs */
  157.     double LOffset;            /* a small shift of the requested luminance range */
  158.     double tolerance;        /* the luminance error corresponding to half 
  159.                                 a step of the coarsest of the variable dacs */
  160.     #if FAST_LUMINANCE
  161.         Fixed _gain[DACS];
  162.         Fixed _VHalfStep;
  163.         Fixed _VFixed;
  164.         Fixed _LOffset;
  165.         Fixed _tolerance;
  166.     #else
  167.         double _gain[DACS];
  168.         double _VHalfStep;
  169.         double _VFixed;
  170.         double _LOffset;
  171.         double _tolerance;
  172.     #endif
  173.     RGBColor rgb;            /* cache the values of the fixed DACs */
  174.     LuminanceTable L;
  175. } LuminanceRecord;
  176.  
  177. typedef LuminanceTable luminanceTable;    // uncapitalized until May, 1995
  178. typedef LuminanceRecord luminanceRecord;// uncapitalized until October 1994.
  179.  
  180. enum {luminanceSet=12345};    /* a unique value that we can check for later */
  181.  
  182. /* Luminance.c */
  183. double EToL(LuminanceRecord *LP,int entry);
  184. int LToE(LuminanceRecord *LP,double L,int firstEntry,int lastEntry);
  185. int LToEOrdered(LuminanceRecord *LP,double L,int firstEntry,int lastEntry);
  186. double SetLuminance(GDHandle device,LuminanceRecord *LP
  187.     ,int theEntry,double luminance
  188.     ,double lowLuminance,double highLuminance);
  189. double SetLuminances(GDHandle device,LuminanceRecord *LP
  190.     ,int firstEntry,int lastEntry
  191.     ,double firstLuminance,double lastLuminance);
  192. double SetLuminancesAndRange(GDHandle device,LuminanceRecord *LP
  193.     ,int firstEntry,int lastEntry
  194.     ,double firstLuminance,double lastLuminance
  195.     ,double lowLuminance,double highLuminance);
  196. void LoadLuminances(GDHandle device, LuminanceRecord *LP,
  197.     int firstEntry, int lastEntry);
  198. void IncrementLuminance(GDHandle device,LuminanceRecord *LP,int theEntry);
  199. double GetLuminance(GDHandle device,LuminanceRecord *LP,int theEntry);
  200. double GetV(GDHandle device,LuminanceRecord *LP,int theEntry);
  201. double VToL(LuminanceRecord *LP,double V);
  202. double LToV(LuminanceRecord *LP,double L);
  203. double LToVFormulaic(LuminanceRecord *LP,double L);
  204. double LToL(LuminanceRecord *LP,double L);
  205.  
  206. /* The following routines are primarily for internal use. */
  207. #if FAST_LUMINANCE
  208.     void _SetLuminance(LuminanceRecord *LPtr,int theEntry,Fixed _luminance);
  209.     Fixed _Tolerance(LuminanceRecord *LP,Fixed _luminance);
  210.     void _SetLuminances(LuminanceRecord *LP,int first,int last
  211.         ,Fixed _firstL,Fixed _dL64,Fixed _firstV,Fixed _lastV);
  212.     Fixed _VToL(LuminanceRecord *LP,Fixed _V);
  213.     Fixed _LToV(LuminanceRecord *LP,Fixed _Lu);
  214. #else
  215.     void _SetLuminance(LuminanceRecord *LPtr,int theEntry,double _luminance);
  216.     double _Tolerance(LuminanceRecord *LP,double _luminance);
  217.     void _SetLuminances(LuminanceRecord *LP,int first,int last
  218.         ,double _firstL,double _dL8,double _firstV,double _lastV);
  219.     double _VToL(LuminanceRecord *LP,double _V);
  220.     double _LToV(LuminanceRecord *LP,double _Lu);
  221. #endif
  222. double SetLuminanceRange(LuminanceRecord *LP
  223.     ,double lowLuminance,double highLuminance);
  224. double VToLPower(LuminanceRecord *LP,double V);            /* use VToL() instead */
  225. double VToLPolynomial(LuminanceRecord *LP,double V);    /* use VToL() instead */
  226. double LToVPower(LuminanceRecord *LP,double L);            /* use LToV() instead */
  227. double LToVPolynomial(LuminanceRecord *LP,double L);    /* use LToV() instead */
  228. double LToVQuadratic(LuminanceRecord *LP,double L);        /* use LToV() instead */
  229.  
  230. /* ReadLuminanceRecord.c */
  231.  
  232. long ReadLuminanceRecord(char *filename,LuminanceRecord *LP,short flags);
  233. long WriteLuminanceRecord(char *filename,LuminanceRecord *LP,short flags);
  234. Description *DescribeLuminanceRecord(LuminanceRecord *LP);
  235.  
  236. #endif /* _LUMINANCE_ */
  237.  
  238.